package com.mlxg.untils.oss;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.ServiceException;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.mlxg.config.oss.ExhibitorAppConfig;
import com.mlxg.untils.file.FileUtils;
import com.mlxg.untils.file.MimeTypeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.UUID;

/**
 * @author cy zhang
 * @version 1.0
 * @date 2025/4/25 14:49
 * 通用上传OSS
 */
@Component
public class GeneralOSSUpLoadUtils {
    private static final Logger logger = LoggerFactory.getLogger(GeneralOSSUpLoadUtils.class);

    @Autowired
    private ExhibitorAppConfig exhibitorAppConfig;

    @Autowired
    private OSS ossClient;

    public String uploadUrlToOss(String source, String ossType) throws IOException {

        String baseUrl = "http://gw.demo365.cc:18086";

        // 获取OSS配置
        String bucketName = exhibitorAppConfig.getAliyunOss().getBucketName();

        // 拆分路径段并逐段编码
        String[] pathSegments = source.split("/");
        StringBuilder encodedPath = new StringBuilder();
        for (String segment : pathSegments) {
            if (segment.isEmpty()) {
                continue;
            }
            String encodedSegment = URLEncoder.encode(segment, StandardCharsets.UTF_8.toString())
                    .replace("+", "%20");
            encodedPath.append("/").append(encodedSegment);
        }

        // 拼接完整的 URL（协议 + 编码后的路径）
        String sourceUrl = baseUrl + encodedPath.toString();
        logger.info("修正后的 URL: {}", sourceUrl); // 检查日志确认格式
        try {

            // 从URL中提取文件名和扩展名
            String originalFilename = extractFileNameFromUrl(sourceUrl);
            String fileExtension = getFileExtension(originalFilename);
            validateFileExtension(fileExtension);
            long fileSize = getFileSizeFromUrl(sourceUrl);
            validateFileSize(fileExtension, fileSize);

            // 生成新文件名
            String newFileName = generateFileName(originalFilename, ossType);

            // 上传文件到OSS
            try (InputStream inputStream = openUrlStream(sourceUrl)) {
                ObjectMetadata metadata = new ObjectMetadata();
                metadata.setContentLength(fileSize);
                metadata.setContentType(MimeTypeUtils.getContextType(fileExtension.toLowerCase()));

                PutObjectRequest request = new PutObjectRequest(bucketName, newFileName, inputStream, metadata);
                ossClient.putObject(request);

                // 构建访问URL
                String ossUrl = buildFileUrl(bucketName, exhibitorAppConfig.getAliyunOss().getEndpoint(), newFileName);
                logger.info("文件上传成功，OSS路径: {}", ossUrl);
                return ossUrl;
            }
        } catch (OSSException | IOException e) {
            logger.error("上传文件到OSS失败: {}", e.getMessage(), e);
            throw new IllegalArgumentException("无效的 URL 格式: " + sourceUrl, e);
//            throw new IOException("上传文件到OSS失败", e);
        }
    }

    private String extractFileNameFromUrl(String url) {
        if (url == null || url.isEmpty()) {
            throw new IllegalArgumentException("无效的URL");
        }

        String[] pathSegments = url.split("/");
        return pathSegments[pathSegments.length - 1];
    }

    private String getFileExtension(String filename) {
        if (filename == null || filename.isEmpty()) {
            throw new IllegalArgumentException("无效的文件名");
        }

        int lastDotIndex = filename.lastIndexOf('.');
        if (lastDotIndex == -1 || lastDotIndex == filename.length() - 1) {
            throw new IllegalArgumentException("文件缺少有效扩展名");
        }
        return filename.substring(lastDotIndex + 1);
    }

    private String generateFileName(String originalFilename, String type) {
        String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
        return type + "/" + UUID.randomUUID().toString() + fileExtension;
    }

    private String buildFileUrl(String bucketName, String endpoint, String fileName) {
        String cleanEndpoint = endpoint.replaceAll("^(http|https)://", "");
        return String.format("https://%s.%s/%s", bucketName, cleanEndpoint, fileName);
    }

    private InputStream openUrlStream(String sourceUrl) throws IOException {
        URL url = new URL(sourceUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
        connection.setConnectTimeout(5000);
        connection.setReadTimeout(20000);

        int responseCode = connection.getResponseCode();
        if (responseCode != HttpURLConnection.HTTP_OK) {
            throw new IOException("HTTP请求失败，状态码: " + responseCode);
        }

        return connection.getInputStream();
    }

    private long getFileSizeFromUrl(String sourceUrl) throws IOException {
        URL url = new URL(sourceUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();

        try {
            connection.setRequestMethod("HEAD");
            long contentLength = connection.getContentLengthLong();
            if (contentLength == -1) {
                logger.warn("无法获取文件大小，将继续上传但可能导致问题");
                // 返回一个默认值或者抛出异常，取决于你的业务需求
                return FileUtils.MAX_FILE_SIZE; // 假设最大大小，允许上传
            }
            return contentLength;
        } catch (ProtocolException e) {
            throw new IllegalArgumentException("无效的 URL 格式: " + sourceUrl, e);
        } finally {
            connection.disconnect();

        }


    }

    private void validateFileExtension(String fileExtension) {
        if (!MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION.contains(fileExtension.toLowerCase())) {
            throw new IllegalArgumentException("仅支持以下文件类型: " + MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
        }
    }

    private void validateFileSize(String fileExtension, long fileSize) {
        // 假设 MimeTypeUtils.VIDEO_EXTENSIONS 包含所有视频格式的扩展名
        boolean isVideo = MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION.contains(fileExtension.toLowerCase());

        if (isVideo && fileSize > FileUtils.MAX_VIDEO_SIZE) {
            throw new IllegalArgumentException("视频文件大小不能超过" + (FileUtils.MAX_VIDEO_SIZE));
        }

        if (fileSize > FileUtils.MAX_FILE_SIZE) {
            throw new IllegalArgumentException("文件大小不能超过" + (FileUtils.MAX_FILE_SIZE));
        }
    }

}
